package com.zhangyj.db;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class ResultSetModel implements IDataModel {
	private NamedPreparedStatement p = null;
	ResultSetMetaData rsmd = null;
	private ResultSet rs = null;
	private Connection conn = null;
	private String sql = null;
	private List<Object> param = null;
	private Map<String, Object> paramMap = null;

	public ResultSetModel(Connection conn, String sql) {
		this.conn = conn;
		this.sql = sql;
	}

	public ResultSetModel(Connection conn, String sql, List<Object> param) {
		this.conn = conn;
		this.sql = sql;
		this.param = param;
	}

	public ResultSetModel(Connection conn, String sql, Map<String, Object> param) {
		this.conn = conn;
		this.sql = sql;
		paramMap = param;
	}

	public ResultSetModel(ResultSet rs) throws SQLException {
		this.rs = rs;
		this.rsmd = rs.getMetaData();
	}

	public void open() throws SQLException {
		try {
			if (rs != null) {
				return;
			}
			p = DBUtil.getNamedPreparedStatement(conn, sql);
			if (this.param != null && this.param.size() > 0) {
				Iterator<Object> iterator = this.param.iterator();
				int index = 1;
				while (iterator.hasNext()) {
					Object obj = iterator.next();
					if (obj instanceof String) {
						p.setString(index, obj.toString());
					} else if (obj instanceof Integer) {
						p.setInt(index, (Integer) obj);
					} else if (obj instanceof Double) {
						p.setDouble(index, (Double) obj);
					} else if (obj instanceof Float) {
						p.setFloat(index, (Float) obj);
					} else {
						p.setString(index, obj.toString());
					}

					index++;
				}
			} else if (this.paramMap != null) {
				Iterator<String> iterator = this.paramMap.keySet().iterator();
				while (iterator.hasNext()) {
					String key = iterator.next();
					Object obj = this.paramMap.get(key);
					if (obj instanceof String) {
						p.setString(key, obj.toString());
					} else if (obj instanceof Integer) {
						p.setInt(key, (Integer) obj);
					} else if (obj instanceof Double) {
						p.setDouble(key, (Double) obj);
					} else if (obj instanceof Float) {
						p.setFloat(key, (Float) obj);
					} else {
						p.setString(key, obj.toString());
					}
				}

			}
			this.rs = p.executeQuery();
			this.rsmd = rs.getMetaData();
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	public int getColumnCount() throws SQLException {
		try {
			return rsmd.getColumnCount();

		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	public String getColumnLabel(int column) throws SQLException {
		try {
			return rsmd.getColumnLabel(column + 1);

		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	public int getColumnType(int column) throws SQLException {
		return rsmd.getColumnType(column + 1);
	}

	public int getColumnDisplaySize(int column) throws SQLException {
		try {
			return rsmd.getColumnDisplaySize(column + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	public int getPrecision(int column) throws SQLException {
		try {
			return rsmd.getPrecision(column + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public void close() throws SQLException {
		try {
			rs.close();
			rs = null;
			p.close();
			p = null;
		} catch (SQLException e) {
			throw new SQLException(e);
		}

	}

	
	public double getDouble(int columnIndex) throws SQLException {
		try {
			return this.rs.getDouble(columnIndex + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public double getDouble(String columnName) throws SQLException {
		try {
			return this.rs.getDouble(columnName);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public float getFloat(int columnIndex) throws SQLException {
		try {
			return this.rs.getFloat(columnIndex + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public float getFloat(String columnName) throws SQLException {
		try {
			return this.rs.getFloat(columnName);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public int getInt(int columnIndex) throws SQLException {
		try {
			return this.rs.getInt(columnIndex + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public int getInt(String columnName) throws SQLException {
		try {
			return this.rs.getInt(columnName);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public String getString(int columnIndex) throws SQLException {
		try {
			return this.rs.getString(columnIndex + 1);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public String getString(String columnName) throws SQLException {
		try {
			return this.rs.getString(columnName);
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

	
	public boolean next() throws SQLException {
		try {
			return this.rs.next();
		} catch (SQLException e) {
			throw new SQLException(e);
		}
	}

}
